#ifndef DEFINE_H
#define DEFINE_H
#pragma once
#include <map>
#include <vector>
#include <list>
#include <sstream>
#define FILE_WRITE(oF,filename) CStdioFile oF;\
	oF.Open(filename,CStdioFile::modeWrite|CStdioFile::modeCreate);
#define FILE_ADD(oF,filename) CStdioFile oF;\
	oF.Open(filename,CStdioFile::modeNoTruncate|CStdioFile::modeCreate);
#define FILE_READ(oF,filename) CStdioFile oF;\
	oF.Open(filename,CStdioFile::modeRead);\
	while(oF.GetLength()!=oF.GetPosition())
#define FILE_READ_VOID(oF,filename) CStdioFile oF;\
	if(!oF.Open(filename,CStdioFile::modeRead)) return;\
	while(oF.GetLength()!=oF.GetPosition())
const double dZero = 1.0E-10;
const int    SCNT=40;
const int    SPOS=1;
const int    SNEG=0;
const int    WORDAPART=50;
const int    NEGDIST=2;
const int    MAX_LEN= 256;
const int    TAG_LEN= 5;
const int    METRIC_COSINE=1;
const int    METRIC_EUCLIDEAN=2;
const int    METRIC_MANHATTAN=3;
enum _CLS_TYPE{TYPE_TRAD,TYPE_WEIGHT};
enum _clsMethod{CLS_KNN,CLS_SVM};
enum _featCat{FEAT_HYBRID,FEAT_STOPWORD};
enum _featType{ftIG,ftCHI,ftMI,ftFISHER};
enum _ORIENT{ORI_NEG,ORI_POS};
enum _NGRAM{UNI_GRAM,BI_GRAM,TRI_GRAM};
enum _NTAG{UNI_TAG,BI_TAG,TRI_TAG};
//
//
typedef enum _CLS_TYPE  CLS_TYPE;
typedef enum _clsMethod clsMethod;
typedef enum _featCat	featCat;
typedef enum _featType	featType;
typedef enum _ORIENT	ORIENT;
typedef enum _NGRAM		NGRAM;
typedef enum _NTAG		NTAG;
typedef std::map<CString,std::vector<int>>       wordCountMap;
typedef std::pair<CString,std::vector<int>>       wordCountPair;
typedef std::map<CString,int>       wordSingleCountMap;
typedef std::pair<CString,int>       wordSingleCountPair;
typedef std::map<CString,double>   wordRateMap;
typedef std::pair<CString,double>  wordRatePair;
typedef std::map<CString,int>       sentiDict; 
typedef std::pair<CString,int>      sentiDictPair;
typedef std::map<CString,wordSingleCountMap> PMIMap;
typedef std::pair<CString,wordSingleCountMap> PMIPair;
typedef std::map<CString,double>	SWTMap;
typedef std::pair<CString,double>	SWTPair;
typedef std::multimap<double,CString>	rateWordMap;
typedef std::pair<double,CString>	rateWordPair;
typedef std::map<int,double>		featRateMap;
typedef std::pair<int,double>       featRatePair;
typedef std::multimap<double,int>       simClsMap;
typedef std::pair<double,int>       simClsPair;
typedef std::vector<std::vector<int>> _2DMatrix;
struct docResult
{
	CString filename;
	int clsId;
	int setId;
};
struct docInfo
{
	int			m_clsid;
	featRateMap m_weights; 
};

struct wordInfo{
CString name;
double  rate;
int     classId;
};
class CGRAMWord
{
public:
	CGRAMWord()
	{}
	CGRAMWord(int size)
	{
		m_size=size;
	}
	CGRAMWord(int size,const char* name)
	{
		m_size=size;
		if(m_size>0)
			m_list.push_back(name);
	}
	void push(const char *name)
	{
		if((int)m_list.size()==m_size)
			m_list.pop_front();
		m_list.push_back(name);
	}
	bool isAvailable()
	{
		return (int)m_list.size()==m_size;
	}
	void toString(char *str,int size=MAX_LEN)
	{
		memcpy(str,"\0",size);
		std::list<std::string>::iterator iter=m_list.begin();
		std::string tmp=*iter;
		iter++;
		for(;iter!=m_list.end();iter++)
		{
			tmp+=" "+*iter;
		}
		strcpy(str,tmp.c_str());
	}
protected:
	std::list<std::string> m_list;
	int m_size;

};
class CTagWord:public CGRAMWord
{
public:
	CTagWord()
	{}
	CTagWord(const char *tagName,int size,const char* name)
	{
		if(strlen(tagName)<TAG_LEN)
		{
			strcpy(m_tagName,tagName);
			m_size=size;
			if(m_size>0)
				m_list.push_back(name);
		}
	}
	CTagWord(const char *tagName,int size)
	{
		if(strlen(tagName)<TAG_LEN)
		{
			strcpy(m_tagName,tagName);
			m_size=size;
		}
	}
	char *getTagName(){
		return m_tagName;
	}
private:
	char m_tagName[TAG_LEN];
};
class CTagWordContainer{
public:
	CTagWordContainer():m_strict(false)
	{}
	CTagWordContainer(int size,bool strict=false)
	{
		m_size=size;
		m_isAvailable=false;
		m_strict=strict;
		memcpy(m_toString,"\0",MAX_LEN);
	}
	void push(char *name,const char *tagName)
	{
		for(int i=0;i<(int)m_tagWordList.size();i++)
		{
			char *curTagName=m_tagWordList[i].getTagName();
			if((m_strict && strcmp(curTagName,tagName)==0)||
			   (!m_strict&& curTagName[0]==tagName[0])
				)
			{
				m_tagWordList[i].push(name);
				m_isAvailable=m_tagWordList[i].isAvailable();
				if(m_isAvailable)
					m_tagWordList[i].toString(m_toString,MAX_LEN);
				else
					memcpy(m_toString,"\0",MAX_LEN);
				return;
			}
		}
		CTagWord tagWord;
		if(!m_strict)
		{
			char shortag[2];
			memcpy(shortag,"\0",2);
			shortag[0]=tagName[0];
			tagWord=CTagWord(shortag,m_size,name);
		}
		else
			tagWord=CTagWord(tagName,m_size,name);
		m_isAvailable=tagWord.isAvailable();
		if(m_isAvailable)
			tagWord.toString(m_toString,MAX_LEN);
		else
			memcpy(m_toString,"\0",MAX_LEN);
		m_tagWordList.push_back(tagWord);
	}
	bool isAvailable()
	{
		return m_isAvailable;
	}
	char *toString()
	{
		return m_toString;
	}
private:
	std::vector<CTagWord> m_tagWordList;
	bool			      m_isAvailable;
	bool                  m_strict;
	char			      m_toString[MAX_LEN];
	int				      m_size;
};
class CWord
{
public:
    CString m_name;
    int m_num;
    CWord(CString name)
    {
        m_name=name;
        m_num=1;
    }
    CWord(const char* name)
    {
        m_name=name;
        m_num=1;
    }
};
#endif